算法Leetcode

Leet Code Report0002 基于链表的大数加法1 [Unchecked] Big Integer法2 统一位数的模拟进位加法3 ***模拟进位加法 + 实时处理0003 最长不重复字母字符串1 HashSet求解2 ***滑动窗口(不定长线段)0005 最长回文字符串1 暴力求解2 ***中心拓展法0006 Z变换1 找规律0007 数字颠倒1 字符串反转0009 判断回文数1 字符串法0010 盛水最多的容器1 暴力求解2 ***双指针法0012 数字转罗马数字1 函数处理法0013 罗马数字转数字1 哈希表映射0014 ***三数之和等于零1 双指针法 + 去重0022 ***生成有效括号1 ***平衡+递归0026 删除数组重复元素1 计算不同的元素2 计算相同的元素0053 ***[简单]最大子序列之和1 DP0121 买卖股票的最佳时机1 暴力搜索2 滑动窗口0062-0063 不同路径1 DP

Leet Code Report

0002 基于链表的大数加法

1 [Unchecked] Big Integer法

方法:先将数据结构中的数据逐个读取,写进StringBuilder,然后构建BigInteger,用封装类计算加法。

注意:本题在leetcode中不能用BigInteger,而且在用ArrayList代替ListNode

2 统一位数的模拟进位加法

位数统一后模拟进位加法,逐个相加。

3 ***模拟进位加法 + 实时处理

不使用额外循环统一位数,在参与计算时用或条件,如果两个链表长度不一,先遍历到终点的链表每次连接一个val=0的节点,这个操作相当于统一位数。此答案不论在时间还是空间上都能超过90%的已提交答案。

0003 最长不重复字母字符串

1 HashSet求解

方法效率低下,时间复杂度O(n^2)。

2 ***滑动窗口(不定长线段)

end指针向后移动,用HashMap记录字符最后一次出现的位置。如果遇到重复且重复的字符在start指针的后面,start指针指向上一次该字符出现位置的下一个位置,作为搜索的起始位置。这样的话无重复的字符串的长度就可以用end - start + 1来表示,代替累加器。

0005 最长回文字符串

1 暴力求解

逐个列举子字符串,看他们是不是回文字符串。加入一句优化,减少遍历次数,主要是针对前期就出现超长回文的情况。勉强通过。

2 ***中心拓展法

以某个字母为中心向两侧对称拓展,以某两个字母为中心向两侧对称拓展,取最大字符串长度,计算起点终点位置截取字符串。

我写的时候用自定义方法isPalindrome()判断,判断一次就要增加 len/2 的时间复杂度,所以效率很低,这位作者专门写了中心拓展的函数

0006 Z变换

1 找规律

0007 数字颠倒

1 字符串反转

数字的绝对值转化为字符串,逆序写入StringBuilder后,添加符号,然后转成数字,用 try catch 防止溢出

0009 判断回文数

1 字符串法

0010 盛水最多的容器

1 暴力求解

双for遍历结合Math.max, Math.min,很容易想到,不写了。

2 ***双指针法

原理:一开始左指针指最左侧,右指针指最右侧,双侧指针尝试向内侧移动,直到重合。移动的原理是:最大矩形面积取决最短线段的长度和两指针间的距离。如果把指向长线段的指针向内侧移动,不但盛水高度没变,距离还变短了,面积自然减少,所以应当把短指针向内侧移动。反之把长指针向内侧移动。

0012 数字转罗马数字

1 函数处理法

0013 罗马数字转数字

1 哈希表映射

罗马数字的原理:如果左侧的字符表示的数字大于右侧,则数字加上左侧(如XI),反之减去左侧(如IV,5-1=4)。所以可以先导入哈希表映射,然后遍历字符串。

0014 ***三数之和等于零

1 双指针法 + 去重

遍历数组,作为第一个数字。遍历过程中选定第一个数字右侧的数字为左指针指向的内容,最后数字为右指针指向的内容。原理和最大盛水容器差不多,如果双指针指向的数字相加小于零,则说明左侧指针指的数字偏小,向右侧移动,反之右侧指针向左侧移动,如果三数相加等于0,则左指针右移到与当前值不同,右指针左移到与当前值不同(去重)。直到左指针位置大于等于右指针,停止搜索。

0022 ***生成有效括号

1 ***平衡+递归

 

0026 删除数组重复元素

1 计算不同的元素

2 计算相同的元素

 

0053 ***[简单]最大子序列之和

1 DP

从第一个数字开始算起,如果遇到sum为负数,则直接舍弃,因为前面部分不可能出现更大的结果了,直接把sum改成遍历到的数字,并继续进行。

 

0121 买卖股票的最佳时机

1 暴力搜索

双for循环,第一个for遍历买到的股票价格,第二个for遍历卖出的股票价格,并用一个max变量保存,时间复杂度O(n^2)。代码省略。

2 滑动窗口

用两个指针lpos rpos,如果此时卖出亏钱,则左指针右移,否则右指针右移,用一个变量记录最大价格。时间复杂度O (n)。

 

0062-0063 不同路径

1 DP

从最左侧列和最上侧列进行递推,很容易完成。

第二题给出了障碍物矩阵,如果某地有障碍则在矩阵中表示为1。解法和第一题类似,只不过Dp时要增加条件,并且在第一行和第一列Dp时,若遇到障碍则应当引发短路,令接下来的Dp全部赋值为0。